﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Wicture.DbRESTFul;
using Wicture.DbRESTFul.SQL;
using Wicture.EPC.Common;
using Wicture.EPC.Service.V1.Models;
using Wicture.EPC.Service.V1.Repository;

namespace Wicture.EPC.Service.V1.QueryInterceptors.Interceptors
{
    public class SaabQueryInterceptor : BaseQueryInterceptor
    {
        private readonly string[] brandCodes = new string[] { "saab" };
        public override string[] BrandCodes => brandCodes;
        #region vin prop
        private static List<VinProp> plants = new List<VinProp>
        {
            new VinProp{ FromYear = 1985, ToYear=1998, Id="1", Name="型号系列V，驾驶员和乘客9000" },
            new VinProp{ FromYear = 1986, ToYear=2002, Id="2", Name="型号系列V，驾驶员和乘客(900/9-3)" },
            new VinProp{ FromYear = 1985, ToYear=2003, Id="7", Name="型号系列V，驾驶员和乘客气囊(900/9-3)" },
            new VinProp{ FromYear = 1985, ToYear=2009, Id="9", Name="型号系列V，驾驶员和乘客气囊" },
            new VinProp{ FromYear = 1998, ToYear=2009, Id="3", Name="型号系列V，驾驶员和乘客" },
            new VinProp{ FromYear = 1987, ToYear=1990, Id="8", Name="型号系列V，驾驶员和乘客气囊(9000)" },
            new VinProp{ FromYear = 2003, ToYear=2009, Id="6", Name="型号系列" },
            new VinProp{ FromYear = 1990, ToYear=1992, Id="5", Name="型号系列V，(900)" },
            new VinProp{ FromYear = 2003, ToYear=2009, Id="1", Name="型号系列" },
            new VinProp{ FromYear = 1990, ToYear=1992, Id="4", Name="型号系列(9000)" },
            new VinProp{ FromYear = 1986, ToYear=1991, Id="3", Name="型号系列"}
        };
        private static List<VinProp> bodys = new List<VinProp> {
            new VinProp { FromYear = 1994, ToYear = 2003, Id = "3", Code = "3D", Name = "3门" },
            new VinProp { FromYear = 1994, ToYear = 2009, Id = "4", Code = "4D", Name = "4门" },
            new VinProp { FromYear = 1994, ToYear = 2009, Id = "5", Code = "5D", Name = "5门" },
            new VinProp { FromYear = 1992, ToYear = 1998, Id = "6", Code = "5CS", Name = "5门9000CS" },
            new VinProp { FromYear = 1986, ToYear = 2009, Id = "7", Code = "CV", Name = "2门敞篷车" },
            new VinProp { FromYear = 1994, ToYear = 2000, Id = "2", Code = "2D", Name = "2门" },
            new VinProp { FromYear = 1986, ToYear = 1993, Id = "3", Code = "3CK", Name = "3门" },
            new VinProp { FromYear = 1986, ToYear = 1993, Id = "5", Code = "5CK", Name = "5门" },
            new VinProp { FromYear = 1986, ToYear = 1993, Id = "2", Code = "2SN", Name = "2门" },
            new VinProp { FromYear = 1986, ToYear = 1993, Id = "4", Code = "4SN", Name = "4门" },
        };
        private static List<VinProp> carlines = new List<VinProp> {
            new VinProp { FromYear = 1986, ToYear = 1994, Id = "A", Code = "1", Name = "Saab 900", FromChassis =0, ToChassis = 999999 },
            new VinProp { FromYear = 1985, ToYear = 1998, Id = "C", Code = "2", Name = "Saab 9000", FromChassis =0, ToChassis = 999999 },
            new VinProp { FromYear = 1994, ToYear = 1997, Id = "D", Code = "1", Name = "Saab 900", FromChassis =0, ToChassis = 999999 },
            new VinProp { FromYear = 1998, ToYear = 2003, Id = "E", Code = "3", Name = "Saab 9-5 (9600)", FromChassis =0, ToChassis = 999999 },
            new VinProp { FromYear = 1998, ToYear = 1998, Id = "D", Code = "1", Name = "Saab 900", FromChassis =0, ToChassis = 999999 },
            new VinProp { FromYear = 1998, ToYear = 1998, Id = "D", Code = "4", Name = "Saab 9-3 (9400)", FromChassis =50001, ToChassis = 999999 },
            new VinProp { FromYear = 1999, ToYear = 2003, Id = "D", Code = "4", Name = "Saab 9-3 (9400)" , FromChassis =0, ToChassis = 999999},
            new VinProp { FromYear = 2003, ToYear = 2009, Id = "F", Code = "5", Name = "Saab 9-3 (9440)", FromChassis =0, ToChassis = 999999 },
            new VinProp { FromYear = 2004, ToYear = 2004, Id = "E", Code = "3", Name = "Saab 9-5 (9600)", FromChassis =0, ToChassis = 999999 },
            new VinProp { FromYear = 2005, ToYear = 2009, Id = "E", Code = "3", Name = "Saab 9-5 (9600)", FromChassis =50001, ToChassis = 999999 },
        };
        private static List<VinProp> engines = new List<VinProp>
        {
           new VinProp { FromYear=1985, ToYear = 1993, Id="L",  Code="B202L", Name="B202L 直列4缸涡轮式发动机" },
           new VinProp { FromYear=1986, ToYear = 1989, Id="J",  Code="B201I", Name="B201I 直列4缸喷油式发动机" },
           new VinProp { FromYear=1986, ToYear = 1989, Id="S",  Code="B201L", Name="B201L 直列4缸涡轮式发动机" },
           new VinProp { FromYear=1986, ToYear = 1993, Id="C",  Code="B201C", Name="B201C 直列4缸化油器式发动机" },
           new VinProp { FromYear=1986, ToYear = 1993, Id="D",  Code="B202I", Name="B202I 直列4缸喷油式发动机" },
           new VinProp { FromYear=1989, ToYear = 1998, Id="B",  Code="B234I", Name="B234I 直列4缸喷油式发动机" },
           new VinProp { FromYear=1990, ToYear = 1993, Id="T",  Code="B202R", Name="B202R 直列4缸涡轮式发动机" },
           new VinProp { FromYear=1990, ToYear = 1994, Id="S",  Code="B202S", Name="B202S 直列4缸涡轮式发动机" },
           new VinProp { FromYear=1991, ToYear = 1993, Id="E",  Code="B212I", Name="B212I 直列4缸喷油式发动机" },
           new VinProp { FromYear=1991, ToYear = 1998, Id="M",  Code="B234L", Name="B234L 直列4缸涡轮式发动机" },
           new VinProp { FromYear=1994, ToYear = 1995, Id="A",  Code="B206I", Name="B206I 直列4缸喷油式发动机" },
           new VinProp { FromYear=1994, ToYear = 1997, Id="P",  Code="B204S", Name="B204S 直列4缸涡轮式发动机" },
           new VinProp { FromYear=1994, ToYear = 1997, Id="V",  Code="B258I", Name="B258I V6喷油式发动机" },
           new VinProp { FromYear=1994, ToYear = 1998, Id="R",  Code="B234R", Name="B234R 直列4缸涡轮式发动机" },
           new VinProp { FromYear=1994, ToYear = 1998, Id="U",  Code="B234E", Name="B234E 直列4缸涡轮式发动机" },
           new VinProp { FromYear=1994, ToYear = 1999, Id="N",  Code="B204L", Name="B204L 直列4缸涡轮式发动机" },
           new VinProp { FromYear=1994, ToYear = 2000, Id="J",  Code="B204I", Name="B204I 直列4缸喷油式发动机" },
           new VinProp { FromYear=1995, ToYear = 1998, Id="W",  Code="B308I", Name="B308I V6喷油式发动机" },
           new VinProp { FromYear=1996, ToYear = 2000, Id="T",  Code="B204E", Name="B204E 直列4缸涡轮式发动机" },
           new VinProp { FromYear=1998, ToYear = 1998, Id="L",  Code="B235L", Name="B235L 直列4缸涡轮式发动机" },
           new VinProp { FromYear=1998, ToYear = 1999, Id="P",  Code="B204R", Name="B204R 直列4缸涡轮式发动机" },
           new VinProp { FromYear=1998, ToYear = 2003, Id="H",  Code="B205L", Name="B205L 直列4缸涡轮式发动机" },
           new VinProp { FromYear=1998, ToYear = 2003, Id="Z",  Code="B308E", Name="B308E V6涡轮式发动机" },
           new VinProp { FromYear=1998, ToYear = 2005, Id="D",  Code="D223L", Name="D223L 直列4缸涡轮柴油发动机" },
           new VinProp { FromYear=1998, ToYear = 2009, Id="C",  Code="B205E", Name="B205E 直列4缸涡轮式发动机" },
           new VinProp { FromYear=1998, ToYear = 2009, Id="E",  Code="B235E", Name="B235E 直列4缸涡轮式发动机" },
           new VinProp { FromYear=1999, ToYear = 2009, Id="G",  Code="B235R", Name="B235R 直列4缸涡轮式发动机" },
           new VinProp { FromYear=2000, ToYear = 2003, Id="K",  Code="B205R", Name="B205R 直列4缸涡轮式发动机" },
           new VinProp { FromYear=2002, ToYear = 2005, Id="L",  Code="D308L", Name="D308L V6涡轮柴油发动机" },
           new VinProp { FromYear=2003, ToYear = 2009, Id="F",  Code="B207E", Name="B207E 直列4缸涡轮式发动机" },
           new VinProp { FromYear=2003, ToYear = 2009, Id="S",  Code="B207L", Name="B207L 直列4缸涡轮式发动机" },
           new VinProp { FromYear=2003, ToYear = 2009, Id="Y",  Code="B207R", Name="B207R 直列4缸涡轮式发动机" },
           new VinProp { FromYear=2004, ToYear = 2007, Id="A",  Code="B235L", Name="B235L 直列4缸涡轮式发动机" },
           new VinProp { FromYear=2004, ToYear = 2009, Id="B",  Code="Z18XE", Name="Z18XE 直列4缸喷油式发动机" },
           new VinProp { FromYear=2005, ToYear = 2005, Id="N",  Code="B207S", Name="B207S 直列4缸涡轮式发动机" },
           new VinProp { FromYear=2005, ToYear = 2009, Id="V",  Code="Z19DT", Name="Z19DT 直列4缸涡轮柴油发动机" },
           new VinProp { FromYear=2005, ToYear = 2009, Id="W",  Code="Z19DTH", Name="Z19DTH 直列4缸涡轮柴油发动机" },
           new VinProp { FromYear=2006, ToYear = 2006, Id="M",  Code="B284E", Name="B284E V6涡轮式发动机" },
           new VinProp { FromYear=2006, ToYear = 2008, Id="U",  Code="B284L", Name="B284L V6涡轮式发动机" },
           new VinProp { FromYear=2008, ToYear = 2009, Id="P",  Code="Z19DTR", Name="Z19DTR 直列4缸涡轮柴油发动机" },
           new VinProp { FromYear=2008, ToYear = 2009, Id="R",  Code="B284R", Name="B284R V6涡轮式发动机"}
        };
        private static List<VinProp> gears = new List<VinProp>
        {
            new VinProp{ FromYear=1985, ToYear=2009, Id="5", Code="M", Name="N5速手排/前轮驱动" },
            new VinProp{ FromYear=1986, ToYear=1994, Id="6", Code="A", Name="N3速自排变速箱" },
            new VinProp{ FromYear=1986, ToYear=2003, Id="8", Code="A", Name="N4速自排变速箱" },
            new VinProp{ FromYear=2002, ToYear=2009, Id="9", Code="A", Name="N5速自排/前轮驱动" },
            new VinProp{ FromYear=2003, ToYear=2009, Id="6", Code="M", Name="N6速手排/前轮驱动" },
            new VinProp{ FromYear=2005, ToYear=2009, Id="1", Code="A", Name="N6速自排/前轮驱动" },
            new VinProp{ FromYear=2008, ToYear=2009, Id="2", Code="A", Name="N6速自排/全四轮驱动" },
            new VinProp{ FromYear=2008, ToYear=2009, Id="7", Code="N", Name="N6速手排/全四轮驱动"}
        };

        private static List<VinProp> markets = new List<VinProp>
        {
            new VinProp {FromYear=1985, ToYear=1994, Id="A", Name="仅供内部使用" },
            new VinProp {FromYear=1985, ToYear=1994, Id="B", Name="仅供内部使用" },
            new VinProp {FromYear=1995, ToYear=2009, Id="N", Name="型号系列V，驾驶员气囊" },
            new VinProp {FromYear=1995, ToYear=2009, Id="P", Name="型号系列V，驾驶员和乘客气囊" },
            new VinProp {FromYear=1985, ToYear=1994, Id="C", Name="型号系列VI，驾驶员气囊" },
            new VinProp {FromYear=1985, ToYear=1994, Id="D", Name="型号系列VI，驾驶员和乘客气囊" },
            new VinProp {FromYear=1985, ToYear=1994, Id="E", Name="仅供内部使用" },
            new VinProp {FromYear=1985, ToYear=1994, Id="F", Name="仅供内部使用" },
            new VinProp {FromYear=1985, ToYear=1994, Id="G", Name="仅供内部使用" },
            new VinProp {FromYear=1985, ToYear=1994, Id="H", Name="仅供内部使用" },
            new VinProp {FromYear=1985, ToYear=1994, Id="J", Name="仅供内部使用" },
            new VinProp {FromYear=1985, ToYear=1994, Id="K", Name="仅供内部使用" },
            new VinProp {FromYear=1985, ToYear=1994, Id="L", Name="仅供内部使用" },
            new VinProp {FromYear=1985, ToYear=1994, Id="M", Name="仅供内部使用" },
            new VinProp {FromYear=1985, ToYear=1994, Id="N", Name="仅供内部使用" },
            new VinProp {FromYear=1985, ToYear=1994, Id="P", Name="仅供内部使用" },
            new VinProp {FromYear=1985, ToYear=1994, Id="R", Name="仅供内部使用" },
            new VinProp {FromYear=1985, ToYear=1994, Id="S", Name="仅供内部使用" },
            new VinProp {FromYear=1985, ToYear=1994, Id="T", Name="仅供内部使用" },
            new VinProp {FromYear=1985, ToYear=1994, Id="U", Name="仅供内部使用" },
            new VinProp {FromYear=1985, ToYear=1994, Id="V", Name="仅供内部使用" },
            new VinProp {FromYear=1985, ToYear=1994, Id="W", Name="仅供内部使用" },
            new VinProp {FromYear=1985, ToYear=1994, Id="X", Name="仅供内部使用" },
            new VinProp {FromYear=1985, ToYear=1994, Id="Y", Name="仅供内部使用" },
            new VinProp {FromYear=1985, ToYear=1994, Id="Z", Name="仅供内部使用" },
            new VinProp {FromYear=1995, ToYear=2009, Id="A", Name="仅供内部使用" },
            new VinProp {FromYear=1995, ToYear=2009, Id="B", Name="仅供内部使用" },
            new VinProp {FromYear=1995, ToYear=2009, Id="C", Name="型号系列I，驾驶员气囊" },
            new VinProp {FromYear=1995, ToYear=2009, Id="D", Name="型号系列I，驾驶员和乘客气囊" },
            new VinProp {FromYear=1995, ToYear=2009, Id="E", Name="型号系列II，驾驶员气囊" },
            new VinProp {FromYear=1995, ToYear=2009, Id="F", Name="型号系列II，驾驶员和乘客气囊" },
            new VinProp {FromYear=1995, ToYear=2009, Id="G", Name="型号系列III，驾驶员气囊" },
            new VinProp {FromYear=1995, ToYear=2009, Id="H", Name="型号系列III，驾驶员和乘客气囊" },
            new VinProp {FromYear=1995, ToYear=2009, Id="K", Name="型号系列IV，驾驶员气囊" },
            new VinProp {FromYear=1995, ToYear=2009, Id="M", Name="型号系列IV，驾驶员和乘客气囊" },
            new VinProp {FromYear=2008, ToYear=2009, Id="Y", Name="Allcarswithoutpassiverestraintsystem" }
        };

        private static Dictionary<string, int> years = new Dictionary<string, int>
        {
        {"B", 1981},
        {"C", 1982},
        {"D", 1983},
        {"E", 1984},
        {"F", 1985},
        {"G", 1986},
        {"H", 1987},
        {"J", 1988},
        {"K", 1989},
        {"L", 1990},
        {"M", 1991},
        {"N", 1992},
        {"P", 1993},
        {"R", 1994},
        {"S", 1995},
        {"T", 1996},
        {"V", 1997},
        {"W", 1998},
        {"X", 1999},
        {"Y", 2000},
        {"1", 2001},
        {"2", 2002},
        {"3", 2003},
        {"4", 2004},
        {"5", 2005},
        {"6", 2006},
        {"7", 2007},
        {"8", 2008},
        {"9", 2009}
        };
        #endregion

        public override object QueryModel(DbRESTFulRepository repository, JObject param)
        {
            Get_Model_InfoParam modelParam = param.ToObject<Get_Model_InfoParam>();
            Get_Model_InfoResult result = new Get_Model_InfoResult();
            if (!string.IsNullOrEmpty(modelParam.vin))
            {
                string vinCode = modelParam.vin;
                VinInfo vinInfo = DecodeVin(vinCode);
                result = repository.Invoke<Get_Model_InfoResult>(CSIs.Query_Model_For_Saab, new { modelCode = vinInfo.Carline.Code, modelYear = vinInfo.Year });
                if (result == null || string.IsNullOrEmpty(result.selectorId))
                {
                    throw new LogicalException($"无法解析此萨博Vin:{vinCode}", 610);
                }
                result.vin = vinCode;
                result.props = new List<Get_Model_InfoResult._props>();
                result.props.Add(new Get_Model_InfoResult._props { key = "组装线", value = vinInfo.Carline.Name });
                result.props.Add(new Get_Model_InfoResult._props { key = "市场/配备", value = vinInfo.Market.Name });
                result.props.Add(new Get_Model_InfoResult._props { key = "车身型式", value = vinInfo.Body.Name });
                result.props.Add(new Get_Model_InfoResult._props { key = "变速箱", value = vinInfo.Gear.Name });
                result.props.Add(new Get_Model_InfoResult._props { key = "发动机", value = vinInfo.Engine.Name });
                result.props.Add(new Get_Model_InfoResult._props { key = "年份", value = vinInfo.Year.ToString() });
                result.props.Add(new Get_Model_InfoResult._props { key = "制造地点", value = vinInfo.Plant.Name });
                result.props.Add(new Get_Model_InfoResult._props { key = "生产系列号", value = vinInfo.Chassis.ToString() });
            }
            else
            {
                var ids = modelParam.id.Split("_");
                if (ids.Count() > 1)
                {
                    modelParam.id = ids[1];
                }
                var model = repository.Invoke(CSIs.Get_Model, modelParam);
                if (model != null)
                {
                    result = JObject.FromObject(model).ToObject<Get_Model_InfoResult>();
                    result.props = GetModelProps(repository, param);
                }
            }
            return result;
        }

        private VinInfo DecodeVin(string vinCode)
        {
            VinInfo vinInfo = new VinInfo();
            string yearId = vinCode.Substring(9, 1);
            if (!years.ContainsKey(yearId))
            {
                throw new LogicalException($"无法解析此萨博Vin:{vinCode}", 610);
            }
            int year = years[yearId];
            int chassisId = vinCode.Substring(11, 6).ToInt();
            string modelId = vinCode.Substring(3, 1);
            vinInfo.Year = year;
            vinInfo.Chassis = chassisId;
            vinInfo.Carline = carlines.Where(q => q.Id == modelId && q.FromYear <= year && q.ToYear >= year && q.FromChassis <= chassisId && q.ToChassis >= chassisId).FirstOrDefault();
            if (vinInfo.Carline == null)
            {
                throw new LogicalException($"无法解析此萨博Vin:{vinCode}", 610);
            }
            string marketId = vinCode.Substring(4, 1);
            vinInfo.Market = markets.Where(q => q.Id == marketId && q.FromYear <= year && q.ToYear >= year).FirstOrDefault();
            if (vinInfo.Market == null)
            {
                throw new LogicalException($"无法解析此萨博Vin:{vinCode}", 610);
            }
            string bodyId = vinCode.Substring(5, 1);
            vinInfo.Body = bodys.Where(q => q.Id == bodyId && q.FromYear <= year && q.ToYear >= year).FirstOrDefault();
            if (vinInfo.Body == null)
            {
                throw new LogicalException($"无法解析此萨博Vin:{vinCode}", 610);
            }
            string gearId = vinCode.Substring(6, 1);
            vinInfo.Gear = gears.Where(q => q.Id == gearId && q.FromYear <= year && q.ToYear >= year).FirstOrDefault();
            if (vinInfo.Gear == null)
            {
                throw new LogicalException($"无法解析此萨博Vin:{vinCode}", 610);
            }
            string engineId = vinCode.Substring(7, 1);
            vinInfo.Engine = engines.Where(q => q.Id == engineId && q.FromYear <= year && q.ToYear >= year).FirstOrDefault();
            if (vinInfo.Engine == null)
            {
                throw new LogicalException($"无法解析此萨博Vin:{vinCode}", 610);
            }
            string plantId = vinCode.Substring(10,1);
            vinInfo.Plant = plants.Where(q=> q.Id == plantId && q.FromYear <= year && q.ToYear >= year).FirstOrDefault();
            if (vinInfo.Plant == null)
            {
                throw new LogicalException($"无法解析此萨博Vin:{vinCode}", 610);
            }
            return vinInfo;
        }

        protected override List<Query_PartsResult> GetParts(DbRESTFulRepository repository, JObject param)
        {
            List<Query_PartsResult> results = repository.Invoke<Query_PartsResult>(CSIs.Query_Parts_For_Saab, param);
            var model = repository.Invoke(CSIs.Get_Model_By_Selector_ID, param);
            string yearStr = model.modelYear;
            int year = yearStr.ToInt();
            foreach (var result in results)
            {
                if(result.saCodeCount > 0)
                {
                    result.partName = result.partName.PadLeft(result.partName.Length + result.saCodeCount, '●');
                }
                result.otherDescription = GetSnGroup(result.imageSN);
                if (result.startTime.HasValue && result.startTime > year)
                {
                    result.belongToVin = false;
                    continue;
                }
                if (result.endTime.HasValue && result.endTime < year)
                {
                    result.belongToVin = false;
                    continue;
                }
            }
            BuildPartResultsByLevel(results);
            return results.Where(q => q.belongToVin).ToList();
        }

        private void BuildPartResultsByLevel(List<Query_PartsResult> results)
        {
            var groups = results.Where(q => !string.IsNullOrEmpty(q.otherDescription)).GroupBy(q => q.otherDescription);
            foreach (var group in groups)
            {
                int maxLevel = group.Max(q => q.saCodeCount);
                if (maxLevel == 0) continue;
                var gg = group.Where(q => q.saCodeCount == maxLevel);
                if (gg.All(q => !q.belongToVin))
                {
                    group.Where(q => q.belongToVin).ForEach(q => q.belongToVin = false);
                }
            }
        }

        private string GetSnGroup(string imageSN)
        {
            if (string.IsNullOrEmpty(imageSN))
            {
                return "";
            }
            StringBuilder sb = new StringBuilder();
            foreach (var c in imageSN)
            {
                if (c >= '0' && c <= '9')
                {
                    sb.Append(c);
                }
                else
                {
                    break;
                }
            }
            return sb.ToString();
        }

        public override object QueryPartDetail(DbRESTFulRepository repository, JObject param)
        {
            param.RemoveEmptyValues();
            var brandCode = param.Value<string>(ParamFields._brandCode);
            var partId = param.Value<string>(ParamFields._partId);
            var partCode = param.Value<string>(ParamFields._partCode);
            dynamic data = null;

            if (string.IsNullOrEmpty(partId))
            {
                data = repository.Invoke(CSIs.Get_Part_Detail_Standard, new { partCode, brandCode });
            }
            else
            {
                data = repository.Invoke(CSIs.Get_Usage_Detail_Standard, param);
            }
            if (data == null) return null;
            // 1、基本信息赋值
            Query_Part_DetailResult result = JObject.FromObject(data).ToObject<Query_Part_DetailResult>();
            result.replacements = new List<Query_Part_DetailResult._replacement>();
            //3.替换件处理
            if (!string.IsNullOrEmpty(result.replacementPartNo))
            {
                List<Query_Part_DetailResult._replacement> replacements = repository.Invoke<Query_Part_DetailResult._replacement>(CSIs.Query_Parts_By_Codes, new { partCodes = result.replacementPartNo.Split(',') });
                if (replacements != null)
                {
                    foreach (var replacement in replacements)
                    {
                        replacement.brandCode = brandCode;
                        replacement.brandName = BrandDictionary.GetName(brandCode);
                        result.replacements.Add(replacement);
                    }
                }
            }
            //4.配件附加属性处理
            var props = new List<Query_Part_DetailResult._prop>
            {
                new Query_Part_DetailResult._prop { key = "件数", value = result.quantity ?? string.Empty },
            };
            result.props = props.Where(q => !string.IsNullOrEmpty(q.value)).ToList();
            return result;
        }

        protected override dynamic GetModelsByPart(DbRESTFulRepository repository, int pageIndex, int pageSize, string brandCode, string partCode)
        {
            return repository.Invoke(CSIs.Query_Models_By_Part_Standard, new { pageIndex, pageSize, brandCode, partCode });
        }

        protected override IEnumerable<Query_SubGroupResult> GetSubGroup(DbRESTFulRepository repository, JObject param)
        {
            return repository.Invoke<Query_SubGroupResult>(CSIs.Query_SubGroup_Standard, param);
        }

        protected override List<Query_SubGroupResult> FilterSubGroupsByVin(DbRESTFulRepository repository, List<Query_SubGroupResult> results, JObject param)
        {
            var vin = param.Value<string>(ParamFields._vin);
            if (string.IsNullOrEmpty(vin) || results == null || results.Count == 0)
            {
                return results;
            }
            var vinInfo = DecodeVin(vin);
            foreach(var result in results)
            {
                if(result.startTime.HasValue && result.startTime > vinInfo.Year)
                {
                    result.belongTo = false;
                    continue;
                }
                if (result.endTime.HasValue && result.endTime < vinInfo.Year)
                {
                    result.belongTo = false;
                    continue;
                }
                string[] props = result.specCodes.Split('|');
                string body = props[0];
                string gear = props[1];
                string engine = props[2];
                if (!string.IsNullOrEmpty(body) && !body.Split(',').Contains(vinInfo.Body.Code))
                {
                    result.belongTo = false;
                    continue;
                }
                if (!string.IsNullOrEmpty(gear) && !gear.Split(',').Contains(vinInfo.Gear.Code))
                {
                    result.belongTo = false;
                    continue;
                }
                if (!string.IsNullOrEmpty(engine) && !engine.Split(',').Any(q=>q.StartsWith(vinInfo.Engine.Code) || vinInfo.Engine.Code.StartsWith(q)))
                {
                    result.belongTo = false;
                    continue;
                }
            }
            return results;
        }
        protected override void FilterPartsByVin(DbRESTFulRepository repository, ref List<Query_PartsResult> results, string vin, string selectorId)
        {
            List<SubGroupInfo> allGroups = null;
            foreach (var result in results)
            {
                if (!string.IsNullOrEmpty(result.refSubGroupCode))
                {
                    if (allGroups == null)
                    {
                        allGroups = repository.Invoke<SubGroupInfo>(CSIs.Query_All_Group_By_SelectorId, new { selectorId });
                    }
                    var subGroupInfo = allGroups.Where(q => q.subGroupCode.TrimStart('0') == result.refSubGroupCode && q.mainGroupCode == result.refMainGroupCode).FirstOrDefault();
                    if (subGroupInfo != null)
                    {
                        result.notes += $"$$参见：<a data='mainGroupId={subGroupInfo.mainGroupId},subGroupId={subGroupInfo.id}'>{result.refMainGroupCode} - {result.refSubGroupCode}</a>";
                        result.notes = result.notes.TrimStart('$');
                    }
                }
            }

            if (string.IsNullOrEmpty(vin))
            {
                return;
            }
            var vinInfo = DecodeVin(vin);
            string chassis8 = vin.Substring(9, 8);
            foreach (var result in results)
            {
                if (result.startTime.HasValue || result.startTime.HasValue)
                {
                    result.weight = 1;
                }
                if (result.startTime.HasValue && result.startTime > vinInfo.Year)
                {
                    result.belongToVin = false;
                    continue;
                }
                if (result.endTime.HasValue && result.endTime < vinInfo.Year)
                {
                    result.belongToVin = false;
                    continue;
                }
                string[] props = result.featureCodes.Split('|');
                string body = props[0];
                string gear = props[1];
                string engine = props[2];
                string chassisStr = props[3].Trim();
                if (!string.IsNullOrEmpty(body) && !body.Split(',').Contains(vinInfo.Body.Code))
                {
                    result.belongToVin = false;
                    continue;
                }
                if (!string.IsNullOrEmpty(gear) && !gear.Split(',').Contains(vinInfo.Gear.Code))
                {
                    result.belongToVin = false;
                    continue;
                }
                if (!string.IsNullOrEmpty(engine) && !engine.Split(',').Any(q => q.StartsWith(vinInfo.Engine.Code) || vinInfo.Engine.Code.StartsWith(q)))
                {
                    result.belongToVin = false;
                    continue;
                }
                if (!string.IsNullOrEmpty(chassisStr))
                {
                    string[] chassisFilters = chassisStr.Split(',');
                    var startChassisFilters = chassisFilters.Where(q => q.EndsWith("--"));
                    var endChassisFilters = chassisFilters.Where(q => q.StartsWith("--"));
                    var isOK = false;
                    if (startChassisFilters.Any())
                    {
                        foreach (var startChassis in startChassisFilters)
                        {
                            if (StringCompare(chassis8, startChassis) > 0)
                            {
                                isOK = true;
                                break;
                            }
                        }
                    }
                    else
                    {
                        isOK = true;
                    }
                    if (!isOK)
                    {
                        result.belongToVin = false;
                        continue;
                    }
                    isOK = false;
                    if (endChassisFilters.Any())
                    {
                        foreach (var endChassis in endChassisFilters)
                        {
                            if (StringCompare(chassis8, endChassis) < 0)
                            {
                                isOK = true;
                                break;
                            }
                        }
                    }
                    else
                    {
                        isOK = true;
                    }
                    if (!isOK)
                    {
                        result.belongToVin = false;
                        continue;
                    }
                }

            }
            BuildPartResultsByLevel(results);
            //var groups = results.Where(q => !string.IsNullOrEmpty(q.imageSN) && q.belongToVin && q.featureCodes.Trim('|') == "").GroupBy(q => q.imageSN);
            //foreach (var group in groups)
            //{
            //    int maxWeight = group.Max(q => q.weight);
            //    group.Where(q => q.weight != maxWeight).ForEach(q => q.belongToVin = false);
            //}
        }


        /// <summary>
        /// 比较相同长度的两个字符串大小
        /// </summary>
        /// <param name="str1"></param>
        /// <param name="str2"></param>
        /// <returns>1: str1大于str2, -1: str1小于str2, 0:str1=str2</returns>
        private int StringCompare(string str1,string str2)
        {
            for (int i = 0; i < str1.Length; i++)
            {
                var a = str1[i];
                var b = str2[i];
                if (a > b)
                {
                    return 1;
                }
                else if (a < b)
                {
                    return -1;
                }
            }

            return 0;
        }

        public class VinProp
        {
            public int FromYear { set; get; }
            public int ToYear { set; get; }
            public string Id { set; get; }
            public string Code { set; get; }
            public string Name { set; get; }
            public int FromChassis { set; get; }
            public int ToChassis { set; get; }
        }
        public class VinInfo
        {
            public VinProp Body { set; get; }
            public VinProp Market { set; get; }
            public VinProp Engine { set; get; }
            public VinProp Gear { set; get; }
            public VinProp Carline { set; get; }
            public VinProp Plant { set; get; }
            public int Chassis { set; get; }
            public int Year { set; get; }
        }
    }
}
